/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Forms;

import Controls.RenderInput;
import Controls.Text;
import Core.ALIGN;
import Core.ContextAction;
import Core.ContextMenu;
import Core.Control;
import Core.ControlImage;
import Core.Form;
import Core.GM;
import Core.Key;
import Core.LayoutManager;
import Core.RecordManager;
import Core.Spacer;
import MathCore.Operands.Variable;
import MathCore.Operators.TrigFunction;
import MathCore.Processor;
import java.util.Enumeration;
import java.util.Vector;

/**
 *
 * @author Александр
 */
public class Editor extends Form
{
	protected Vector fields;

	private ContextMenu optionsMenu = new ContextMenu(this);
	private ContextMenu angleMenu = new ContextMenu(this);
	private ContextAction opt_angles, opt_addvar, opt_remvar, angle_degree, angle_radian, angle_grad, back, angle_back;
	private ControlImage img_r, img_d, img_g;

	public static Processor proc;

	public Editor()
	{
		super(Form.HEAD|Form.THICK_PANEL);

		body.spacing = 0;
		body.scrollEnable = true;

		opt_angles = new ContextAction("Angle units", angleMenu);
		opt_addvar = new ContextAction("New variable");
		opt_remvar = new ContextAction("Remove variable");

		angle_degree = new ContextAction("Degrees");
		angle_grad = new ContextAction("Grads");
		angle_radian = new ContextAction("Radians");

		back = new ContextAction("Back");
		angle_back = new ContextAction("Back", optionsMenu);

		optionsMenu.addAction(opt_addvar);
		optionsMenu.addAction(opt_remvar);
		optionsMenu.addAction(opt_angles);
		optionsMenu.addAction(back);

		angleMenu.addAction(angle_radian);
		angleMenu.addAction(angle_degree);
		angleMenu.addAction(angle_grad);
		angleMenu.addAction(angle_back);

		img_d = new ControlImage("/status_degree.png", ALIGN.RIGHT);
		img_r = new ControlImage("/status_radian.png", ALIGN.RIGHT);
		img_g = new ControlImage("/status_grad.png", ALIGN.RIGHT);

		switch(RecordManager.getRecord("CalcForm.angle", TrigFunction.ANGLE_RADIAN))
		{
			case TrigFunction.ANGLE_RADIAN:
				TrigFunction.angleType = TrigFunction.ANGLE_RADIAN;
				setWindowIcon(img_r);
				break;

			case TrigFunction.ANGLE_DEGREE:
				TrigFunction.angleType = TrigFunction.ANGLE_DEGREE;
				setWindowIcon(img_d);
				break;

			case TrigFunction.ANGLE_GRAD:
				TrigFunction.angleType = TrigFunction.ANGLE_GRAD;
				setWindowIcon(img_g);
				break;
		}

		proc = new Processor();
		fields = new Vector();

		initFields();
		setWindowText(GM.FORM_CAPTION, "Calculation");
		initText();	
	}

	protected void initFields()
	{
		addField("a", AddVar.TOP);
	}

	protected RenderInput addField(String name, int align)
	{

		Variable attached = new Variable(null, name);
		proc.addVariable(attached);

		RenderInput input = new RenderInput(body.getAvailableW(), attached, RenderInput.STYLE_NAME_AND_RESULT, this);

		if(body.getActiveControl() == null || body.getControls().isEmpty() || align == AddVar.BOTTOM)
		{
			body.addControl(input);
			fields.addElement(input);
		}
		else if(align == AddVar.TOP)
		{
			body.insertControlBefore(input, body.getControl(0));
			fields.insertElementAt(input, 0);
		}
		else if(align == AddVar.BELOW)
		{
			body.insertControlAfter(input, body.getActiveControl());
			int index = body.getControls().indexOf(input);
			fields.insertElementAt(input, index);
		}
		else if(align == AddVar.ABOVE)
		{
			body.insertControlBefore(input, body.getActiveControl());
			int index = body.getControls().indexOf(input) + 1;
			fields.insertElementAt(input, index);
		}

		body.switchSelectTo(input);

		recalcAll();

		return input;
	}

	public void onEvent(int event, Object param)
	{
		super.onEvent(event, param);

		if(event == GM.CONTROL_RELEASED)
		{
			initText();
			recalcAll();
		}
		else if(event == GM.PANEL_STAR)
		{
			if(body.getRealActiveControl() == null || body.getRealActiveControl().getState() != Control.PRESSED)
			{
				proc = null;
				close();
			}
		}
		else if(event == GM.PANEL_RIGHTSOFT)
		{
			if(body.getRealActiveControl() != null && body.getRealActiveControl().getState() != Control.PRESSED) exec();
		}
		else if(event == GM.CONTEXT_RELEASED)
		{
			if(param == opt_addvar)
			{
				AddVar av = new AddVar();
			}
			if(param == opt_remvar)
			{
				remField();
			}
			if(param == angle_degree)
			{
				TrigFunction.angleType = TrigFunction.ANGLE_DEGREE;
				setWindowIcon(img_d);
				RecordManager.setRecord("CalcForm.angle", TrigFunction.angleType);
				recalcAll();
			}
			if(param == angle_grad)
			{
				TrigFunction.angleType = TrigFunction.ANGLE_GRAD;
				setWindowIcon(img_g);
				RecordManager.setRecord("CalcForm.angle", TrigFunction.angleType);
				recalcAll();
			}
			if(param == angle_radian)
			{
				TrigFunction.angleType = TrigFunction.ANGLE_RADIAN;
				setWindowIcon(img_r);
				RecordManager.setRecord("CalcForm.angle", TrigFunction.angleType);
				recalcAll();
			}
		}
		else if(event == GM.PANEL_LEFTSOFT)
		{
			if(body.getRealActiveControl() == null || body.getRealActiveControl().getState() != Control.PRESSED) optionsMenu.show(panel.getCoord(), ALIGN.LEFT | ALIGN.BOTTOM);
		}
		else if(event == GM.UPPER_FORM_CLOSED && param instanceof AddVar)
		{
			AddVar av = (AddVar) param;
			if(av.align != -1) addField(av.varName, av.align);
		}
	}

	private void remField()
	{
		RenderInput field = (RenderInput) body.getRealActiveControl();
		if(field == null) return;

		fields.removeElement(field);
		body.select(Control.UNDER);
		proc.removeVariable(field.attachedVar);
		body.removeControl(field);
		recalcAll();
	}

	protected void initText()
	{
		setWindowText(GM.PANEL_LEFTSOFT, "Menu");
		setWindowText(GM.PANEL_RIGHTSOFT, "");
		setWindowText(GM.PANEL_STAR, "Back");
		setWindowText(GM.PANEL_POUND, "");
		setWindowText(GM.PANEL_CENTER, "Edit");
	}

	protected void exec()
	{
		for(Enumeration e = fields.elements(); e.hasMoreElements(); )
		{
			RenderInput field = (RenderInput) e.nextElement();
			System.out.println(field.attachedVar.getName()+": "+field.getExpression());
		}
	}

	private void recalcAll()
	{
		for(Enumeration e = fields.elements(); e.hasMoreElements(); )
		{
			RenderInput field = (RenderInput) e.nextElement();
			field.recalc();
		}
	}

	public void processKey(int key, int state)
	{
		super.processKey(key, state);

		if(state != Key.RELEASED && body.getActiveControl().getState() != Control.PRESSED)
		{
			switch(key)
			{
				case Key.PL_KEY: ((RenderInput)body.getActiveControl()).scrollLeft(); break;
				case Key.PR_KEY: ((RenderInput)body.getActiveControl()).scrollRight(); break;
			}
		}
	}


}
